package com.mvp.base;

import android.support.annotation.NonNull;

import com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter;
import com.hannesdorfmann.mosby3.mvp.MvpView;
import com.mvp.base.model.ResultModel;
import com.mvp.helper.AbsCrashHelper;
import com.mvp.networking.ApiErrorHelper;
import com.mvp.networking.NetTransformer;
import com.mvp.utils.ToastUtil;

import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * Created by zhangyuncai on 2018/9/11.
 */

public class BasePresenter<T extends MvpView> extends MvpNullObjectBasePresenter<T> implements LoadMvpView {

    protected CompositeDisposable composite;
    protected LoadMvpView loadMvpView;

    @Override
    public void attachView(@NonNull T view) {
        super.attachView(view);
        if (view != null && view instanceof LoadMvpView) {
            loadMvpView = (LoadMvpView) view;
        }
        this.composite = new CompositeDisposable();
    }

    @Override
    public void detachView(boolean retainInstance) {
        super.detachView(retainInstance);
        if (!retainInstance && composite != null && !composite.isDisposed()) {
            composite.dispose();
        }
    }

    /**
     * 常用方法
     *
     * @param observable
     * @param resultConsumer
     * @param <B>
     */
    public <B> void baseSubscribe(Observable<B> observable, Consumer<B> resultConsumer) {
        baseSubscribe(observable, null, resultConsumer, null);
    }

    public <B> void baseSubscribe(Observable<B> observable, Consumer<B> resultConsumer,Consumer<Throwable> throwableConsumer) {
        baseSubscribe(observable, null, resultConsumer, throwableConsumer);
    }

    public <B> void baseSubscribe(Observable<B> observable, NetParams netParams, Consumer<B> resultConsumer) {
        baseSubscribe(observable, netParams, resultConsumer, null);
    }


    /**
     * 最终走向
     *
     * @param observable
     * @param netParams
     * @param resultConsumer
     * @param throwableConsumer
     * @param <B>
     */
    public <B> void baseSubscribe(Observable<B> observable, NetParams netParams, Consumer<B> resultConsumer, Consumer<Throwable> throwableConsumer) {
        if (resultConsumer == null) {
            ToastUtil.showToast("resultConsumer==null!!");
            return;
        }
        if (netParams == null) {
            netParams = new NetParams();
        }
        NetParams finalNetParams = netParams;
        Disposable subscribe = observable.compose(new NetTransformer<B>(loadMvpView, netParams))
                .subscribe(b -> {
                    if (b instanceof ResultModel) {
                        ResultModel resultModel = (ResultModel) b;
                        if (!resultModel.isSuccess()) {
                            if (finalNetParams.isToastError()) {
                                ToastUtil.showToast(resultModel.getMsg());
                            }
                            AbsCrashHelper.postCatchedException(new Throwable(resultModel.getMsg()));
                        }
                    }
                    resultConsumer.accept(b);
                }, throwable -> {
                    throwable.printStackTrace();
                    if (loadMvpView != null) {
                        loadMvpView.showLoadingFailureError(throwable);
                    }
                    ApiErrorHelper.handleCommonError(throwable);
                    if (throwableConsumer != null) {
                        throwableConsumer.accept(throwable);
                    }
                });
        composite.add(subscribe);
    }

    @Override
    public void showLoadingBar(Object showTag) {
        if (loadMvpView != null) {
            loadMvpView.showLoadingBar(showTag);
        }
    }

    @Override
    public void dismissLoadingBar(Object dississTag) {
        if (loadMvpView != null) {
            loadMvpView.dismissLoadingBar(dississTag);
        }
    }

    public void dismissAllLoadingBar() {
        if (loadMvpView != null) {
            loadMvpView.dismissLoadingBar("all");
        }
    }

    @Override
    public void showLoadingFailureError(Throwable throwable) {
        if (loadMvpView != null) {
            loadMvpView.showLoadingFailureError(throwable);
        }
    }
}
